#pragma once
#include "mb.h"
namespace SOUI {

    class SMBJsFunBinder {
        /*jsValue js_msgBox(jsExecState es,void *param)
        {
            SWkeWebkit *_THIS = (SWkeWebkit*)param;
        }*/
    };
    
#define EVT_MB_BEGIN (EVT_EXTERNAL_BEGIN + 600)
#define EVT_MB_UPDATATITLE (EVT_MB_BEGIN + 1)
#define EVT_MB_UPDATAURL (EVT_MB_BEGIN + 2)
#define EVT_MB_NEW_NAV (EVT_MB_BEGIN + 3)
    
    class EventMBBrowserTitleChanged : public TplEventArgs < EventMBBrowserTitleChanged > {
        SOUI_CLASS_NAME(EventMBBrowserTitleChanged, L"on_title_changed")
      public:
        EventMBBrowserTitleChanged(SWindow *pSender) : TplEventArgs<EventMBBrowserTitleChanged>(pSender) {
        }
        enum {
            EventID = EVT_MB_UPDATATITLE
        };
        LPCWSTR   pszTitle;
        int       iId;
    };
    class EventMBBrowserUrlChanged : public TplEventArgs < EventMBBrowserUrlChanged > {
        SOUI_CLASS_NAME(EventMBBrowserUrlChanged, L"on_url_changed")
      public:
        EventMBBrowserUrlChanged(SWindow *pSender) : TplEventArgs<EventMBBrowserUrlChanged>(pSender) {
        }
        enum {
            EventID = EVT_MB_UPDATAURL
        };
        LPCWSTR     pszUrl;
        int         iId;
    };
    
    class EventMBBrowserNewNav : public TplEventArgs < EventMBBrowserNewNav > {
        SOUI_CLASS_NAME(EventMBBrowserNewNav, L"on_new_nav")
      public:
        EventMBBrowserNewNav(SWindow *pSender) : TplEventArgs<EventMBBrowserNewNav>(pSender), pRetView(NULL) {
        }
        enum {
            EventID = EVT_MB_NEW_NAV
        };
        LPCWSTR     pszUrl;
        int         iId;
        mbWebView   pRetView;
    };
    
    typedef std::function<BOOL(const char *url, void *job)>    hook_url_call;
    typedef std::function<void(int customMsg, const char *jsArg)>   hook_js_call;
    
    class SMBWebView: public SWindow {
        SOUI_CLASS_NAME(SMBWebView, L"mbweb")
      public:
        SMBWebView(void);
        ~SMBWebView(void);
        mbWebView   GetWebView() {
            return m_pWebView;
        }
        
        void LoadURL(LPCWSTR url);
        SStringW GetURL();
        
        void ReLoad();
        bool DownloadCallback(mbWebView webView, const mb_utf8 *url);
        void URLChangedCallback(mbWebView webView, const mb_utf8 *url);
        void TitleChangedCallback(mbWebView webView, const mb_utf8 *url);
        mbWebView CreateViewCallback(mbWebView webView,
                                     mbNavigationType navigationType, const mb_utf8 *url,
                                     const mbWindowFeatures *windowFeatures);
                                     
        void StopLoading();
        void GoBack();
        void GoForward();
        
        void RunJS(const SStringA &strValue);
        void HookUrl(hook_url_call call);
        void HookJS(hook_js_call call);
        
      protected:
        void BindCallBackFunToWeb();
        int OnCreate(void *);
        void OnDestroy();
        void OnPaint(IRenderTarget *pRT);
        void OnSize(UINT nType, CSize size);
        void OnMove(CPoint pt);
        void OnShowWindow(BOOL bShow, UINT nStatus);
        
        LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam);
        LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam);
        LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam);
        LRESULT OnKeyUp(UINT uMsg, WPARAM wParam, LPARAM lParam);
        LRESULT OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam);
        LRESULT OnImeStartComposition(UINT uMsg, WPARAM wParam, LPARAM lParam);
        
        void OnSetFocus(SWND wndOld);
        void OnKillFocus(SWND wndFocus);
        virtual BOOL OnSetCursor(const CPoint &pt);
        virtual UINT OnGetDlgCode() {
            return SC_WANTALLKEYS;
        }
        LRESULT OnAttrUrl(SStringW strValue, BOOL bLoading);
        SOUI_ATTRS_BEGIN()
        ATTR_CUSTOM(L"url", OnAttrUrl)
        SOUI_ATTRS_END()
        
        SOUI_MSG_MAP_BEGIN()
        MSG_WM_PAINT_EX(OnPaint)
        MSG_WM_CREATE(OnCreate)
        MSG_WM_DESTROY(OnDestroy)
        MSG_WM_SIZE(OnSize)
        MSG_WM_SETFOCUS_EX(OnSetFocus)
        MSG_WM_KILLFOCUS_EX(OnKillFocus)
        MSG_WM_SHOWWINDOW(OnShowWindow)
        MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, 0x209, OnMouseEvent)
        MESSAGE_HANDLER_EX(WM_MOUSEWHEEL, OnMouseWheel)
        MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyDown)
        MESSAGE_HANDLER_EX(WM_KEYUP, OnKeyUp)
        MESSAGE_HANDLER_EX(WM_CHAR, OnChar)
        MESSAGE_HANDLER_EX(WM_IME_STARTCOMPOSITION, OnImeStartComposition)
        
        SOUI_MSG_MAP_END()
        
      protected:
        mbWebView m_pWebView;
        SStringW m_strUrl;
        CSize m_szRtSize;
        
        hook_url_call m_hook_url;
        hook_js_call m_hook_js;
        friend void MB_CALL_TYPE onRunJs(mbWebView webView, void *param, mbJsExecState es, mbJsValue v);
        friend BOOL MB_CALL_TYPE _mbLoadUrlBeginCallback(mbWebView webView, void *param, const char *url, void *job);
        friend void MB_CALL_TYPE _mbNativeFunction(mbWebView webView, void *param, mbJsExecState es, int64_t queryId,
                int customMsg, const mb_utf8 *request);
    };
}
